#include "http_hand.h"
#include <cctype>
#include <cstddef>
#include <cstdio>
#include <cstring>
#include <strings.h>
#include <sys/socket.h>
#include <unistd.h>
int get_line(int fd,char buf[]){
	int i=0;
	char c=0;
	while (i<SIZE&&c!='\n') {
		int ret=recv(fd,&c,1,0);
		if(ret>0&&c=='\r'){
			recv(fd,&c,1,MSG_PEEK);
			if(c!='\n'){
				c='\n';
			}
		}
		buf[i++]=c;
	}
	buf[i]=0;
	return i;
} 


//将十六进制字符转换为对应的整数值
static int hex_to_int(char c) {
    if (c >= '0' && c <= '9') return c - '0';
    if (c >= 'a' && c <= 'f') return 10 + c - 'a';
    if (c >= 'A' && c <= 'F') return 10 + c - 'A';
    return -1; // 无效的十六进制字符
}

static void url_decode_robust(const char* encoded,char *url) { //解码url
    if (encoded == NULL) return;
    int length = strlen(encoded); 
    int j = 0;
    for (int i = 0; i < length; i++) {
        if (encoded[i] == '%') {
            if (i + 2 < length) {
                int high = hex_to_int(encoded[i+1]);
                int low = hex_to_int(encoded[i+2]);
                
                if (high >= 0 && low >= 0) {
                    url[j++] = (char)((high << 4) | low);
                    i += 2;
                } else {
                    // 无效的编码，保留原样
                    url[j++] = encoded[i];
                }
            } else {
                // 不完整的编码，保留原样
                url[j++] = encoded[i];
            }
        } else if (encoded[i] == '+') {
            url[j++] = ' ';
        } else {
            url[j++] = encoded[i];
        }
    }
    url[j] = '\0';
}

void http_connect(int fd){
	char requst_buf[SIZE];
	bzero(requst_buf,SIZE);
	recv(fd,requst_buf,SIZE,MSG_PEEK);
	#if 1
		printf("----------------------\n");
		printf("%s\n",requst_buf);
		printf("----------------------\n");
	#endif
	//处理http请求
	int i=0;
	char buf[SIZE];
	int l_len=get_line(fd,buf);
	char method[32];//存储请求方法的变量
	int k=0;
	for (;i<l_len; i++) {
		if (isspace(buf[i])) {
			break;
		}
		method[k++]=buf[i];
	}
	method[k]=0;
	if (strcmp(method,"GET")!=0&&strcmp(method,"POST")!=0) {
		echo_error(fd,405);
	}
	else{
		int need_handler=0;	//	判断是否需要对界面进行手动处理，1要，0不要
		if(strcasecmp(method,"POST")==0){
			need_handler=1;
		}
		for (;i<l_len&&isspace(buf[i])!=0; i++);//将空格跳过
		char fir_URL[SIZE];
		int u=0;
		char *querry_string=NULL;	//指向url中要处理的数据的起始地址
		for (;i<l_len; i++) {
			if (isspace(buf[i])) {
				buf[i]='\0';
				break;
			}
			if (buf[i]=='?') {
				querry_string=&buf[i+1];
				continue;
			}
			fir_URL[u++]=buf[i];
		}
		fir_URL[u]=0;
		char URL[SIZE];
		url_decode_robust(fir_URL,URL);
		cout<<"URL:"<<URL<<endl;
		char path[SIZE]="";
		if (strstr(URL,"file")) {
			sprintf(path,"/home/rayfileweb%s",URL);
		}
		else{
			sprintf(path,"/home/rayfileweb/html%s",URL);
		}
		if (path[strlen(path)-1]=='/') {
			strcat(path,"index.html");
		}
		//判断当前服务器中有该文件
		struct stat st;	//定义文件状态的结构体
		if(stat(path,&st)==-1){
			printf("can not find\n");
			echo_error(fd,404);
		}//获取文件的状态,返回-1则表示要访问的文件不存在
		else{
			if (querry_string!=NULL) {
				need_handler=1;
			}
			if (need_handler) {
				handler_request(fd,method,path,querry_string);
			}else {
				echo_www(fd,path,st.st_size);
			}
		}
	}
	//任务已经处理完成
	char zbuf[1];
	while (1) {
		int n=read(fd,zbuf,sizeof(zbuf));
		if (n==0) {
			break;
		}
	}
	close(fd);
}